package sample.mybatis.web;

import com.alibaba.fastjson.JSON;
import com.dt.activity.center.bo.activity.ActivityBO;
import com.dt.activity.center.bo.activity.ActivityCountBO;
import com.dt.activity.center.bo.activity.ActivityPageBO;
import com.dt.activity.center.bo.activity.ActivityTypeBO;
import com.dt.activity.center.bo.trends.TrendsBO;
import com.dt.activity.center.config.BusinessConfig;
import com.dt.activity.center.constant.Constant;
import com.dt.activity.center.dto.activity.ActivityDetailDTO;
import com.dt.activity.center.dto.activity.ActivityMyCountQueryDTO;
import com.dt.activity.center.dto.activity.ActivityPageDTO;
import com.dt.activity.center.dto.trends.TrendsQueryDTO;
import com.dt.activity.center.enums.trends.TrendsSourceTypeEnum;
import com.dt.activity.center.facade.activity.ActivityConverter;
import com.dt.activity.center.facade.activity.ActivityTypeConverter;
import com.dt.activity.center.facade.trends.TrendsConverter;
import com.dt.activity.center.feign.server.dto.ActivityCountQueryFeignDTO;
import com.dt.activity.center.feign.server.vo.ActivityCountQueryFeignVO;
import com.dt.activity.center.service.activity.ActivityReader;
import com.dt.activity.center.service.activity.ActivityTypeReader;
import com.dt.activity.center.service.trends.TrendsReader;
import com.dt.activity.center.web.model.activity.*;
import com.dt.activity.center.web.model.trends.TrendsVO;
import com.dt.framework.business.component.whiteuri.WhiteUri;
import com.dt.framework.business.component.whiteuri.WhiteUriCategory;
import com.dt.framework.business.constant.BusinessCode;
import com.dt.framework.business.constant.HttpRequestHeaderConstant;
import com.dt.framework.core.exception.BusinessException;
import com.dt.framework.core.mvc.Pagination;
import com.dt.framework.core.mvc.WebResult;
import com.dt.framework.core.utils.DtRequestContextHolder;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 活动表 (Activity)表控制层
 *
 * @author zhangzy
 * @since 2021-06-24 12:20:16
 */
@RestController
@RequestMapping("/activity")
@AllArgsConstructor
@Api(tags = "活动管理-查询-张子元")
public class ActivityController {

    private final ActivityReader activityReader;

    private final ActivityConverter activityConverter;

    private final ActivityTypeReader activityTypeReader;

    private final ActivityTypeConverter activityTypeConverter;

    private final TrendsReader trendsReader;

    private final TrendsConverter trendsConverter;

    private final BusinessConfig businessConfig;

    @WhiteUri(category = WhiteUriCategory.AccessToken)
    @ApiOperation("分页查询活动列表")
    @GetMapping("/page")
    public WebResult<Pagination<ActivityPageVO>> page(
            @ApiParam("关键字") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam("学段") @RequestParam(value = "stageId", required = false) String stageId,
            @ApiParam("学科") @RequestParam(value = "subjectId", required = false) String subjectId,
            @ApiParam("外部业务id1,双师管理端传的机构id获取可管理活动列表") @RequestParam(value = "bizId1", required = false) String bizId1,
            @ApiParam("外部业务id2,双师用户机构id获取可参加活动列表") @RequestParam(value = "bizId2", required = false) String bizId2,
            @ApiParam("外部业务id3") @RequestParam(value = "bizId3", required = false) String bizId3,
            @ApiParam("外部业务id4") @RequestParam(value = "bizId4", required = false) String bizId4,
            @ApiParam("业务场景集合{default:默认；doubleTeacher:双师；schoolWand:入校中台；yxb:研修宝；school:校本}") @RequestParam(value = "scene", required = false) List<String> scene,
            @ApiParam("活动列表范围 全部:all;我的活动列表:my") @RequestParam(value = "scope", required = false) String scope,
            @ApiParam("活动业务状态 0:全部;11-未开始;12-进行中;20:已结束") @RequestParam(value = "activityStatus", required = false) String activityStatus,
            @ApiParam("置顶状态 全部:all;置顶:top;非置顶:notTop") @RequestParam(value = "topStatus", defaultValue = "all", required = false) String topStatus,
            @ApiParam("我在活动下的角色 全部:all;我参加的:member;我创建的:creator;我主持的:host;我管理的:admin") @RequestParam(value = "roleKey", required = false) String roleKey,
            @ApiParam("活动邀请码") @RequestParam(value = "activityCode", required = false) String activityCode,
            @ApiParam("创建时间-起始时间") @RequestParam(value = "startCreateTime", required = false) String startCreateTime,
            @ApiParam("创建时间-终止时间") @RequestParam(value = "endCreateTime", required = false) String endCreateTime,
            @ApiParam("排序{全部:all,最新:new,最热:hot,最近(大于等于当前日期):near}") @RequestParam(value = "orderBy", required = false) String orderBy,
            @ApiParam(value = "每页数量， 默认20") @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
            @ApiParam(value = "页号， 默认1") @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
            @ApiParam("指定空间") @RequestParam(value = "tenant", required = false) String tenant,

            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {

        if (CollectionUtils.isEmpty(scene)) {
            throw new BusinessException(BusinessCode.ACTIVITY_PARAMETER_ERROR_CODE, "入参场景不允许为空");
        }
        ActivityPageDTO activityPageDTO = ActivityPageDTO.builder()
                .keyword(keyword)
                .stageId(stageId)
                .subjectId(subjectId)
                .scope(scope)
                .activityStatus(activityStatus)
                .topStatus(topStatus)
                .roleKey(roleKey)
                .bizId1(bizId1)
                .bizId2(bizId2)
                .bizId3(bizId3)
                .bizId4(bizId4)
                .bizTypeList(scene)
                .dtTenant(StringUtils.isNotBlank(tenant) ? tenant : DtRequestContextHolder.getRequestTenant())
                // 双师管理端入参参数 start
                .activityCode(activityCode)
                .startCreateTime(startCreateTime)
                .endCreateTime(endCreateTime)

                .orderBy(orderBy)
                .pageSize(pageSize)
                .pageIndex(pageIndex)
                .userId(userId)
                .build();

        Pagination<ActivityPageBO> activityBOPagination = activityReader.page(activityPageDTO);

        Pagination<ActivityPageVO> pagination = new Pagination<>();
        pagination.setPageIndex(pageIndex);
        pagination.setPageSize(pageSize);
        pagination.setTotal(activityBOPagination.getTotal());
        pagination.setRows(CollectionUtils.isEmpty(activityBOPagination.getRows()) ? null
                : activityBOPagination.getRows().stream().map(n -> activityConverter.convertPageBoToVo(n))
                        .collect(Collectors.toList()));

        return WebResult.successData(pagination);
    }

    @WhiteUri(category = WhiteUriCategory.AccessToken)
    @ApiOperation("通过活动id或访问码查询活动详情")
    @GetMapping("/detail")
    public WebResult<ActivityVO> getActivityById(
            @ApiParam("活动id") @RequestParam(value = "activityId", required = false) Long activityId,
            @ApiParam("活动访问码") @RequestParam(value = "activityCode", required = false) String activityCode,
            @ApiParam("bizId2 双师用户所在机构id") @RequestParam(value = "bizId2", required = false) String bizId2,
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {
        ActivityDetailDTO activityDetailDTO = ActivityDetailDTO.builder()
                .activityId(activityId)
                .activityCode(activityCode)
                .bizId2(bizId2)
                .userId(userId)
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .build();
        ActivityBO activityBO = activityReader.selectActivityDetail(activityDetailDTO);

        ActivityVO activityVO = activityConverter.convertBoToVo(activityBO);

        return WebResult.successData(activityVO);
    }

    @ApiOperation("通过活动id或访问码查询活动基础数据 有缓存")
    @GetMapping("/baseDetail")
    public WebResult<ActivityVO> getActivityById(
            @ApiParam("活动id") @RequestParam(value = "activityId", required = true) Long activityId,
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {
        ActivityDetailDTO activityDetailDTO = ActivityDetailDTO.builder()
                .activityId(activityId)
                .userId(userId)
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .build();
        ActivityBO activityBO = activityReader.selectActivityBaseDetail(activityDetailDTO);

        ActivityVO activityVO = activityConverter.convertBoToVo(activityBO);

        return WebResult.successData(activityVO);
    }

    @ApiOperation("查询该用户常用的标签列表")
    @GetMapping("/user/typeTags")
    public WebResult<List<String>> userTypeTags(
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {
        return WebResult.successData(activityReader.userTypeTags(userId));
    }

    // @ApiOperation("活动年级字典")
    // @GetMapping("/user/typeTags")
    // public WebResult<List<String>> userTypeTags(@RequestHeader(value =
    // HttpRequestHeaderConstant.USER_ID,required = false) Long userId) {
    // return WebResult.successData(activityReader.userTypeTags(userId));
    // }

    @ApiOperation("活动类型字典")
    @GetMapping("/types")
    public WebResult<List<ActivityTypeVO>> types(
            @ApiParam("业务场景集合{default:默认；doubleTeacher:双师；schoolWand:入校中台；yxb:研修宝；school:校本}") @RequestParam(value = "scene", required = false) String scene) {
        List<ActivityTypeBO> types = activityTypeReader.types(scene);

        return WebResult
                .successData(types.stream().map(activityTypeConverter::convertBoToVo).collect(Collectors.toList()));
    }

    @WhiteUri(category = WhiteUriCategory.AccessToken)
    @ApiOperation("活动动态")
    @GetMapping("/trends")
    public WebResult<List<TrendsVO>> trends() {

        // 按空间划分
        TrendsQueryDTO trendsQueryDTO = TrendsQueryDTO.builder()
                .sourceType(TrendsSourceTypeEnum.ACTIVITY.getType())
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .build();
        List<TrendsBO> trends = trendsReader.trends(trendsQueryDTO);

        return WebResult.successData(trends.stream().map(trendsConverter::convertBoToVo).collect(Collectors.toList()));
    }

    @ApiOperation("我的活动数量")
    @GetMapping("/my/count")
    public WebResult<ActivityCountVO> myCount(
            @ApiParam("用户id 传则查询该用户的数据,不传则查询当前登录用户的数据") @RequestParam(value = "userId", required = false) Long userId,
            @ApiParam(value = "查询范围:tenant:空间下;brand:品牌下;all:不限空间品牌;dtBrandList:指定品牌列表;默认brand") @RequestParam(value = "scope", required = false, defaultValue = "brand") String scope,
            @ApiParam("品牌列表,多个用','分割 查询范围 为指定品牌时使用") @RequestParam(value = "dtBrandList", required = false) String dtBrandList,
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long currUserId) {
        Long queryUserId;
        if (userId != null) {
            queryUserId = userId;
        } else if (currUserId != null) {
            queryUserId = currUserId;
        } else {
            throw new BusinessException(BusinessCode.ACTIVITY_PARAMETER_ERROR_CODE, "没有要查询的用户");
        }
        // 按空间划分
        ActivityMyCountQueryDTO activityMyCountQueryDTO = ActivityMyCountQueryDTO.builder()
                .userId(queryUserId)
                .build();
        if ("tenant".equals(scope)) {
            activityMyCountQueryDTO.setDtTenant(DtRequestContextHolder.getRequestTenant());

        }
        if ("brand".equals(scope)) {
            activityMyCountQueryDTO.setDtBrand(DtRequestContextHolder.getRequestBrand());
            activityMyCountQueryDTO.setDtTenant(DtRequestContextHolder.getRequestTenant());

        }
        /**
         * 品牌集合
         */
        if (!StringUtils.isEmpty(scope) && Constant.DT_BRAND_LIST.equals(scope)) {
            if (StringUtils.isBlank(dtBrandList)) {
                /**
                 * 入参品牌集合为空,直接返回空数据
                 */
                return WebResult.successData(ActivityCountVO.builder()
                        .adminCount(0)
                        .creatorCount(0)
                        .memberCount(0)
                        .hostCount(0)
                        .build());
            }
            String[] arr = dtBrandList.split(",");
            activityMyCountQueryDTO.setDtBrandList(Lists.newArrayList(arr));
        }
        ActivityCountBO activityCountBO = activityReader.myCount(activityMyCountQueryDTO);
        ActivityCountVO activityCountVO = activityConverter.convertCountBoToVo(activityCountBO);
        return WebResult.successData(activityCountVO);
    }

    @ApiOperation("后台：全部活动列表")
    @RequestMapping("/operate/all/page")
    public WebResult<Pagination<ActivityManagementListVO>> operateAllPage(
            @ApiParam("活动标题或创建人") @RequestParam(value = "titleOrCreatorName", required = false) String titleOrCreatorName,
            @ApiParam("活动邀请码") @RequestParam(value = "activityCode", required = false) String activityCode,
            @ApiParam("学段") @RequestParam(value = "stageId", required = false) String stageId,
            @ApiParam("学科") @RequestParam(value = "subjectId", required = false) String subjectId,
            @ApiParam("活动状态") @RequestParam(value = "activityState", required = false) Integer activityState,
            @ApiParam("发布状态1发布0未发布") @RequestParam(value = "publishState", required = false) Integer publishState,
            @ApiParam("置顶1置顶0不置顶") @RequestParam(value = "top", required = false) Integer top,
            @ApiParam("创建时间-起始时间") @RequestParam(value = "startCreateTime", required = false) Long startCreateTime,
            @ApiParam("创建时间-终止时间") @RequestParam(value = "endCreateTime", required = false) Long endCreateTime,
            @ApiParam("主题") @RequestParam(value = "theme", required = false) String theme,
            @ApiParam("组织1") @RequestParam(value = "orgKeyWord1", required = false) String orgKeyWord1,
            @ApiParam("组织2") @RequestParam(value = "orgKeyWord2", required = false) String orgKeyWord2,
            @ApiParam("每页数量， 默认20") @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
            @ApiParam("页号， 默认1") @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {
        ActivityPageDTO dto = ActivityPageDTO.builder()
                .stageId(stageId)
                .subjectId(subjectId)
                .titleOrCreatorName(titleOrCreatorName)
                .top(top)
                .activityCode(activityCode)
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .orgKeyWord1(orgKeyWord1)
                .orgKeyWord2(orgKeyWord2)
                .activityState(activityState)
                .theme(theme)
                .startTime(Objects.nonNull(startCreateTime) ? new Date(startCreateTime) : null)
                .endTime(Objects.nonNull(endCreateTime) ? new Date(endCreateTime) : null)
                .pageIndex(pageIndex)
                .pageSize(pageSize)
                .userId(userId)
                .showScope(publishState)
                .invalid(Constant.VALID)
                .sort(Constant.SORT_CREATE_TIME_DESC)
                .build();
        Pagination<ActivityManagementListVO> result = activityReader.operatePlanAllPage(dto);
        return WebResult.successData(result);
    }

    @WhiteUri(category = WhiteUriCategory.AccessToken)
    @ApiOperation("在线教研")
    @GetMapping("/online/page")
    public WebResult<Pagination<ActivityPlanListVO>> onlinePage(
            @ApiParam("搜索活动") @RequestParam(value = "titleOrCode", required = false) String titleOrCode,
            @ApiParam("学段(必传小初高)") @RequestParam(value = "stageId") String stageId,
            @ApiParam("学科") @RequestParam(value = "subjectId", required = false) String subjectId,
            @ApiParam("活动状态(1-关闭禁用 ；11-未开始；12-进行中;20:已结束)") @RequestParam(value = "activityState", required = false) Integer activityState,
            @ApiParam("主题") @RequestParam(value = "theme", required = false) String theme,
            @ApiParam("组织1") @RequestParam(value = "orgKeyWord1", required = false) String orgKeyWord1,
            @ApiParam("组织2") @RequestParam(value = "orgKeyWord2", required = false) String orgKeyWord2,
            @ApiParam("每页数量， 默认20") @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
            @ApiParam("页号， 默认1") @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex) {
        ActivityPageDTO dto = ActivityPageDTO.builder()
                .stageId(stageId)
                .subjectId(subjectId)
                .titleOrCode(titleOrCode)
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .orgKeyWord1(orgKeyWord1)
                .orgKeyWord2(orgKeyWord2)
                .activityState(activityState)
                .theme(theme)
                .showScope(1)
                .invalid(Constant.VALID)
                .pageIndex(pageIndex)
                .pageSize(pageSize)
                .sort(Constant.SORT_START_TIME_DESC)
                .build();

        Pagination<ActivityPlanListVO> result = activityReader.onlinePlanPage(dto);
        return WebResult.successData(result);
    }

    @ApiOperation("活动基础列表")
    @GetMapping("/base/page")
    public WebResult<Pagination<ActivityBaseListVO>> basePage(
            @ApiParam("搜索活动") @RequestParam(value = "titleOrCode", required = false) String titleOrCode,
            @ApiParam("每页数量， 默认20") @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
            @ApiParam("页号， 默认1") @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
            @RequestHeader(value = HttpRequestHeaderConstant.USER_ID, required = false) Long userId) {
        ActivityPageDTO dto = ActivityPageDTO.builder()
                .titleOrCode(titleOrCode)
                .dtTenant(DtRequestContextHolder.getRequestTenant())
                .dtBrand(DtRequestContextHolder.getRequestBrand())
                .invalid(Constant.VALID)
                .pageIndex(pageIndex)
                .pageSize(pageSize)
                .userId(userId)
                .build();

        Pagination<ActivityBaseListVO> result = activityReader.basePage(dto);
        return WebResult.successData(result);
    }

    @WhiteUri(category = WhiteUriCategory.AccessToken)
    @ApiOperation("根据场景获取主题及组织单位数据")
    @GetMapping("/themeAndOrg")
    public WebResult<TemplateThemeAndOrgVO> themeAndOrg(
            @ApiParam("业务场景{smartZxjy:国家智慧教育}") @RequestParam(value = "scene", required = true) String scene) {
        return WebResult.successData(activityReader.themeAndOrg(scene));
    }

    @ApiOperation("获取某种类型下时间范围内活动发布数量")
    @PostMapping("/activityCountQuery")
    public ActivityCountQueryFeignVO activityCountQuery(@RequestBody ActivityCountQueryFeignDTO request) {

        return activityReader.activityCountQuery(request);
    }

    @ApiOperation("获取活动样例模板")
    @GetMapping("/getSampleList")
    public WebResult<List<ActivitySampleVO>> getSampleList(
            @ApiParam("业务场景{xicheng:西城}") @RequestParam(value = "scene", required = true) String scene) {

        String activitySampleJson = businessConfig.getActivitySampleJson();
        List<SceneActivitySampleVO> sceneList = JSON.parseArray(activitySampleJson, SceneActivitySampleVO.class);
        List<ActivitySampleVO> result = sceneList.stream().filter(e -> e.getScene().equals(scene)).findFirst()
                .orElse(new SceneActivitySampleVO()).getSampleList();
        return WebResult.successData(result);
    }

    @ApiOperation("获取J02相关字典")
    @GetMapping("/getActivityResearchDict")
    public WebResult<ActivityResearchDictVO> getActivityResearchDict(
            @ApiParam("业务场景{xxzx:信息中心J02}") @RequestParam(value = "scene", required = true) String scene) {
        return WebResult.successData(activityReader.getActivityResearchDict(scene));
    }
}
